/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bobDict;

import bobDict.data.*;
import java.awt.Dimension;
import java.io.File;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.text.Document;
import userInterface.GUI;

/**
 *
 * @author imed
 */
public class DictManager extends javax.swing.JFrame {

    
    protected GUI fatherDialog = null;
    
    /**
     * Creates new form DictManager
     */
    public DictManager( GUI fatherDialog ) {
        this.fatherDialog = fatherDialog;
        initComponents();
        setSizeNLocation();
        resetTables();
    }
    
    private void setSizeNLocation(){
        
        // set size
        int width = 800, height = 700;
        Dimension dialogSize = new Dimension(width, height);
        this.setPreferredSize( dialogSize );
        this.setSize(dialogSize);
        
        // set location
        this.setLocationRelativeTo(  fatherDialog );
                
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jPanel2 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        jPanel4 = new javax.swing.JPanel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jPanel6 = new javax.swing.JPanel();
        jPanel7 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jTable2 = new javax.swing.JTable();
        jPanel8 = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        jTable3 = new javax.swing.JTable();
        jPanel5 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();
        jPanel9 = new javax.swing.JPanel();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("eHOST-BoB Dictionary Manager");

        jPanel1.setBackground(new java.awt.Color(255, 254, 253));
        jPanel1.setBorder(javax.swing.BorderFactory.createMatteBorder(5, 3, 5, 3, new java.awt.Color(255, 254, 253)));
        jPanel1.setLayout(new java.awt.BorderLayout());

        jLabel1.setFont(new java.awt.Font("Trebuchet MS", 1, 12)); // NOI18N
        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/setting_big.jpeg"))); // NOI18N
        jLabel1.setText("eHOST-BoB Dictionary Manager");
        jPanel1.add(jLabel1, java.awt.BorderLayout.NORTH);

        jPanel2.setBackground(new java.awt.Color(255, 254, 253));
        jPanel2.setBorder(javax.swing.BorderFactory.createMatteBorder(10, 0, 0, 10, new java.awt.Color(255, 254, 253)));
        jPanel2.setLayout(new java.awt.BorderLayout());

        jButton1.setFont(new java.awt.Font("Trebuchet MS", 0, 12)); // NOI18N
        jButton1.setText("Load");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jPanel2.add(jButton1, java.awt.BorderLayout.WEST);

        jPanel3.setBackground(new java.awt.Color(255, 254, 253));
        jPanel3.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, new java.awt.Color(0, 51, 153)));
        jPanel3.setLayout(new java.awt.BorderLayout());

        jLabel2.setFont(new java.awt.Font("Trebuchet MS", 0, 12)); // NOI18N
        jLabel2.setText("PHIconcepts_v09.confscore.xml");
        jPanel3.add(jLabel2, java.awt.BorderLayout.CENTER);

        jPanel2.add(jPanel3, java.awt.BorderLayout.CENTER);

        jPanel1.add(jPanel2, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);

        jPanel4.setLayout(new java.awt.BorderLayout());

        jSplitPane1.setBackground(new java.awt.Color(255, 254, 253));
        jSplitPane1.setDividerLocation(200);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setResizeWeight(0.5);

        jPanel6.setBackground(new java.awt.Color(255, 254, 253));
        jPanel6.setBorder(javax.swing.BorderFactory.createMatteBorder(9, 10, 0, 10, new java.awt.Color(255, 254, 253)));
        jPanel6.setLayout(new java.awt.GridLayout(1, 2, 2, 0));

        jPanel7.setBackground(new java.awt.Color(255, 254, 253));
        jPanel7.setLayout(new java.awt.BorderLayout());

        jLabel4.setFont(new java.awt.Font("Trebuchet MS", 1, 12)); // NOI18N
        jLabel4.setText("Objective Annotation");
        jPanel7.add(jLabel4, java.awt.BorderLayout.NORTH);

        jTable2.setFont(new java.awt.Font("Trebuchet MS", 0, 12)); // NOI18N
        jTable2.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null}
            },
            new String [] {
                "id", "type", "group begin", "group end", "features"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jTable2.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jTable2.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTable2MouseClicked(evt);
            }
        });
        jTable2.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jTable2KeyReleased(evt);
            }
        });
        jScrollPane2.setViewportView(jTable2);

        jPanel7.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        jPanel6.add(jPanel7);

        jPanel8.setBackground(new java.awt.Color(255, 254, 253));
        jPanel8.setLayout(new java.awt.BorderLayout());

        jLabel5.setFont(new java.awt.Font("Trebuchet MS", 1, 12)); // NOI18N
        jLabel5.setText("Rules");
        jPanel8.add(jLabel5, java.awt.BorderLayout.NORTH);

        jTable3.setFont(new java.awt.Font("Trebuchet MS", 0, 12)); // NOI18N
        jTable3.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null, null},
                {null, null, null, null, null},
                {null, null, null, null, null}
            },
            new String [] {
                "id", "regEx", "matchStrategy", "matchType", "confidence"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jTable3.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane3.setViewportView(jTable3);

        jPanel8.add(jScrollPane3, java.awt.BorderLayout.CENTER);

        jPanel6.add(jPanel8);

        jSplitPane1.setRightComponent(jPanel6);

        jPanel5.setBackground(new java.awt.Color(255, 254, 253));
        jPanel5.setBorder(javax.swing.BorderFactory.createMatteBorder(5, 10, 0, 10, new java.awt.Color(255, 254, 253)));
        jPanel5.setMaximumSize(null);
        jPanel5.setMinimumSize(null);
        jPanel5.setPreferredSize(null);
        jPanel5.setLayout(new java.awt.BorderLayout());

        jLabel3.setFont(new java.awt.Font("Trebuchet MS", 1, 12)); // NOI18N
        jLabel3.setText("BoB Variable Table");
        jPanel5.add(jLabel3, java.awt.BorderLayout.NORTH);

        jTable1.setFont(new java.awt.Font("Trebuchet MS", 0, 12)); // NOI18N
        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "Variable Name", "Value/Regex"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        jTable1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane1.setViewportView(jTable1);

        jPanel5.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jSplitPane1.setLeftComponent(jPanel5);

        jPanel4.add(jSplitPane1, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel4, java.awt.BorderLayout.CENTER);

        jPanel9.setBackground(new java.awt.Color(204, 204, 204));
        jPanel9.setPreferredSize(new java.awt.Dimension(0, 23));
        jPanel9.setLayout(new java.awt.GridLayout(1, 5));

        jButton2.setText("Apply RegEx");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        jPanel9.add(jButton2);

        jButton3.setText("Close");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });
        jPanel9.add(jButton3);

        getContentPane().add(jPanel9, java.awt.BorderLayout.PAGE_END);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        
        // clear old data
        dictionary.clear();
        
        // reload dictionary
        bobDict.analyst.Loader loader = new bobDict.analyst.Loader();
        String path = (new File("")).getAbsolutePath();
        loader.loadXML( new File( path + File.separatorChar +jLabel2.getText() ) );
        
        // list data
        display();
        
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jTable2MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTable2MouseClicked
        showRules();
    }//GEN-LAST:event_jTable2MouseClicked

    private void jTable2KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTable2KeyReleased
        showRules();        // TODO add your handling code here:
    }//GEN-LAST:event_jTable2KeyReleased

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        this.dispose();
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        startRegex();
    }//GEN-LAST:event_jButton2ActionPerformed

    
    private void startRegex(){
        Document doc = this.fatherDialog.getDoc();
        if(( doc == null )||(doc.getLength()<1))
            return;
        
        // reorgnize regex / replace all variables
        replaceVariables();
        
        // start regex
        regex(doc);
        
        this.fatherDialog.refresh();
    }
    
    private void replaceVariables(){
        if( dictionary.variables==null)
            return;
        if( dictionary.variables.variables.size() < 1 )
            return;
        
        for( String varname : dictionary.variables.variables.keySet() ){
            if(( varname == null )||(varname.trim().length()<1))
                continue;
            varname = varname.trim();
            String value = dictionary.variables.variables.get( varname );
            if(( value == null )||(value.trim().length()<1))
                continue;
            value = value.trim();
            
            varname = "\\{" + varname + "\\}";
            
            for(String conceptname : dictionary.concepts.concepts.keySet() ){
                ConceptDef concept = dictionary.concepts.concepts.get( conceptname );
                if( concept == null )
                    continue;
                if((concept.rules ==null)||(concept.rules.rules==null))
                    continue;
                for(Rule rule :concept.rules.rules){
                    //int i=rule.regEx.length();
                    //System.out.println(rule.regEx);
                    rule.regEx = rule.regEx.replaceAll(varname, value);
                    //int j=rule.regEx.length();
                    //if( i!=j ){
                    //    System.out.println(rule.regEx + "\n\n");
                    //}
                }
            }
        }
    }
    
    HashSet<String> newclasses = new HashSet<String>();
    
    private void regex(Document doc) {
        if (doc == null) {
            return;
        }
        if (doc.getLength() < 1) {
            return;
        }
        
        String doctext = null;
        try {
            doctext = doc.getText(0, doc.getLength() - 1);
        } catch (Exception ex) {
            ex.printStackTrace();
            return;
        }

        for (String conceptname : dictionary.concepts.concepts.keySet()) {
            ConceptDef concept = dictionary.concepts.concepts.get(conceptname);
            if (concept == null) {
                continue;
            }
            if ((concept.rules == null) || (concept.rules.rules == null)) {
                continue;
            }
            for (Rule rule : concept.rules.rules) {
                if (rule == null) 
                    continue;                
                if ((rule.regEx == null) || (rule.regEx.trim().length() < 1)) 
                    continue;
                
                regex( doctext, rule.regEx, concept.annotationrule.type );
                
                this.newclasses.add( concept.annotationrule.type );
                
            }
        }

    }
    
    private void regex( String doctext, String regEx, String type ){
        if((type==null)||(type.trim().length()<1))
            return;
        
        try{
            Matcher matcher;
            boolean match_found;
            matcher = Pattern.compile( regEx, Pattern.CASE_INSENSITIVE ).matcher( doctext );
            match_found = matcher.find();

            while(match_found){
                 int start = matcher.start();
                 int end = matcher.end();
                 String spantext = doctext.substring(start, end);
                 
                 // record this one
                 System.out.println("\n\n" + spantext);
                 resultEditor.annotations.Depot depot = new resultEditor.annotations.Depot();
                 String testsourceFilename = resultEditor.workSpace.WorkSet.getCurrentFile().getName().trim();
                 String time = commons.Tools.getTimeStamper();
                 depot.addANewAnnotation( testsourceFilename, spantext, start, end, time, type, "eHOST-BoB", "000", null, null, assignMeAUniqueIndex());
                 
                 match_found = matcher.find(start+1);
            }
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }
    
    private int assignMeAUniqueIndex(){
         return resultEditor.annotations.AnnotationIndex.newAnnotationIndex();
    }
    
    private void showRules(){
        DefaultTableModel tableModel1 = (DefaultTableModel) jTable3.getModel();
        tableModel1.setRowCount(0);// 清除原有行
        
        int selectRows=jTable2.getSelectedRows().length;// 取得用户所选行的行数
        DefaultTableModel tableModel = (DefaultTableModel) jTable2.getModel();

        if(selectRows==1){
            int selectedRowIndex = jTable2.getSelectedRow(); // 取得用户所选单行  
            
            int i=0;
            for( String name : dictionary.concepts.concepts.keySet() ){
                if(i==selectedRowIndex){
                    ConceptDef concept = dictionary.concepts.concepts.get(name);
                    Rules rules = concept.rules;
                    for(Rule rule : rules.rules){
                        String[] arr=new String[5];
                        arr[0] = rule.ruleId;
                        arr[1] = rule.regEx;
                        arr[2] = rule.matchType;
                        arr[3] = rule.matchStrategy;
                        arr[4] = rule.confidence;
                        tableModel1.addRow(arr);
                    }
                    break;
                
                }
                
                i++;
            }
            
        }
        
        jTable3.invalidate();
    }
    
    /**show loaded bob dictionary on tables*/
    private void display(){
        resetTables();
        showVariables();
        showAnnotations();
        
        jTable2.setRowSelectionAllowed( true);
        jTable2.setRowSelectionInterval(0, 0); 
        showRules();
    }    
    
    private void resetTables(){
        TableColumn firsetColumn = jTable1.getColumnModel().getColumn(0);
        firsetColumn.setPreferredWidth(200);
        firsetColumn.setMaxWidth(200);
        firsetColumn.setMinWidth(200);
    }
    
    private void showVariables(){
        DefaultTableModel tableModel = (DefaultTableModel) jTable1.getModel();
        tableModel.setRowCount(0);// 清除原有行
  
        int rowNum = dictionary.variables.size();
        // 填充数据
        for( String name : dictionary.variables.variables.keySet() ){
            String value = dictionary.variables.variables.get(name);
            String[] arr=new String[2];
            arr[0]=name;
            arr[1]=value;
            tableModel.addRow(arr);
        }
                          
        // update table
        jTable1.invalidate();
    }
    
    private void showAnnotations(){
        DefaultTableModel tableModel = (DefaultTableModel) jTable2.getModel();
        tableModel.setRowCount(0);// 清除原有行
  
        //int rowNum = dictionary.variables.size();
        // 填充数据
        for( String name : dictionary.concepts.concepts.keySet() ){
            ConceptDef concept = dictionary.concepts.concepts.get(name);
            AnnotationRule ar = concept.annotationrule;
            String[] arr=new String[5];
            arr[0]=ar.id;
            arr[1]=ar.type;
            arr[2] = ar.groupbegin;
            arr[3] = ar.groupend;
            arr[4] = ar.featuresToString();
            tableModel.addRow(arr);
        }
                          
        // update table
        jTable2.invalidate();
    }
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTable jTable1;
    private javax.swing.JTable jTable2;
    private javax.swing.JTable jTable3;
    // End of variables declaration//GEN-END:variables
}
